﻿// -------------------------------------------------------------------------
//    @FileName         :    BagSystemTestBase.cpp
//    @Author           :    gaoyi
//    @Date             :    2025/1/20
//    @Email            :    445267987@qq.com
//    @Module           :    BagSystemTestBase
//
// -------------------------------------------------------------------------

#include "BagSystemTestBase.h"
#include <iostream>
#include <algorithm>
#include <chrono>

// 静态成员变量初始化
MockItemDesc* BagSystemTestBase::s_mockItemDesc = nullptr;

// 构造函数
BagSystemTestBase::BagSystemTestBase() 
    : m_randomGen(m_randomDevice()), 
      m_testCounter(0),
      m_setupCompleted(false),
      m_teardownCompleted(false) {
}

// 析构函数
BagSystemTestBase::~BagSystemTestBase() {
}

// 静态设置，在所有测试前运行一次
void BagSystemTestBase::SetUpTestSuite() {
    std::cout << "初始化背包系统测试环境..." << std::endl;
    
    // 创建Mock物品描述
    s_mockItemDesc = new MockItemDesc();
    s_mockItemDesc->Initialize();
    
    std::cout << "背包系统测试环境初始化完成" << std::endl;
}

// 静态清理，在所有测试后运行一次
void BagSystemTestBase::TearDownTestSuite() {
    std::cout << "清理背包系统测试环境..." << std::endl;
    
    if (s_mockItemDesc) {
        delete s_mockItemDesc;
        s_mockItemDesc = nullptr;
    }
    
    std::cout << "背包系统测试环境清理完成" << std::endl;
}

// 测试设置
void BagSystemTestBase::SetUp() {
    // 重置计数器
    m_testCounter = 0;
    
    // 清理之前的测试数据
    m_testBagPages.clear();
    m_testBagOpMgrs.clear();
    
    // 创建测试用玩家
    m_testPlayer = std::make_unique<NFPlayer>();
    if (m_testPlayer) {
        // 初始化玩家数据
        // 这里可以添加更多的玩家初始化逻辑
    }
    
    m_setupCompleted = true;
}

// 测试清理
void BagSystemTestBase::TearDown() {
    // 清理测试数据
    m_testBagOpMgrs.clear();
    m_testBagPages.clear();
    m_testPlayer.reset();
    
    m_teardownCompleted = true;
}

// 创建测试用的玩家对象
NFPlayer* BagSystemTestBase::CreateTestPlayer(uint64_t playerId, const std::string& playerName) {
    if (!m_testPlayer) {
        m_testPlayer = std::make_unique<NFPlayer>();
    }
    
    // 设置玩家基本信息
    // 这里需要根据实际的NFPlayer类接口来设置
    // m_testPlayer->SetPlayerId(playerId);
    // m_testPlayer->SetPlayerName(playerName);
    
    return m_testPlayer.get();
}

// 创建测试用的物品
NFGridItem BagSystemTestBase::CreateTestItem(int itemId, int count, int quality, bool bind) {
    NFGridItem item;
    
    // 设置物品基本属性
    item.SetItemID(itemId);
    item.SetNumber(count);
    item.SetQuality(quality);
    item.SetBind(bind);
    
    // 生成唯一UUID
    static uint64_t uuidCounter = 1000;
    item.SetUUID(++uuidCounter);
    
    return item;
}

// 创建测试用的装备
NFGridItem BagSystemTestBase::CreateTestEquip(int equipId, int quality, int level) {
    NFGridItem equip = CreateTestItem(equipId, 1, quality, false);
    
    // 设置装备特有属性
    // 这里需要根据实际的装备数据结构来设置
    // 如果有装备扩展数据，在这里设置
    
    return equip;
}

// 创建测试用的背包页面
NFBagPage* BagSystemTestBase::CreateTestBagPage(int bagType, int maxGrid) {
    auto bagPage = std::make_unique<NFBagPage>();
    
    // 初始化背包页面
    // bagPage->Initialize(bagType, maxGrid);
    
    NFBagPage* result = bagPage.get();
    m_testBagPages.push_back(std::move(bagPage));
    
    return result;
}

// 创建测试用的背包操作管理器
NFBagPageOpMgr* BagSystemTestBase::CreateTestBagOpMgr(NFPlayer* player, int reason, bool needCommit) {
    if (!player) {
        player = CreateTestPlayer();
    }
    
    auto bagOpMgr = std::make_unique<NFBagPageOpMgr>(player, reason, needCommit);
    
    NFBagPageOpMgr* result = bagOpMgr.get();
    m_testBagOpMgrs.push_back(std::move(bagOpMgr));
    
    return result;
}

// 验证背包页面状态
void BagSystemTestBase::VerifyBagPageState(NFBagPage* bagPage, int expectedUsedCount, int expectedEmptyCount) {
    ASSERT_NE(bagPage, nullptr) << "背包页面不能为空";
    
    // 验证使用的格子数
    int actualUsedCount = 0;
    int actualEmptyCount = 0;
    
    for (int i = 0; i < bagPage->GetMaxGrid(); ++i) {
        const NFGridItem* item = bagPage->GetItem(i);
        if (item && !item->IsEmpty()) {
            actualUsedCount++;
        } else {
            actualEmptyCount++;
        }
    }
    
    ASSERT_EQ(actualUsedCount, expectedUsedCount) << "背包使用格子数不符合预期";
    ASSERT_EQ(actualEmptyCount, expectedEmptyCount) << "背包空闲格子数不符合预期";
}

// 验证物品属性
void BagSystemTestBase::VerifyItemProperties(const NFGridItem& item, int expectedId, int expectedCount, int expectedQuality) {
    ASSERT_EQ(item.GetItemID(), expectedId) << "物品ID不符合预期";
    ASSERT_EQ(item.GetNumber(), expectedCount) << "物品数量不符合预期";
    ASSERT_EQ(item.GetQuality(), expectedQuality) << "物品品质不符合预期";
}

// 验证背包中是否包含指定物品
bool BagSystemTestBase::VerifyItemInBag(NFBagPage* bagPage, int itemId, int expectedCount) {
    if (!bagPage) {
        return false;
    }
    
    int actualCount = 0;
    for (int i = 0; i < bagPage->GetMaxGrid(); ++i) {
        const NFGridItem* item = bagPage->GetItem(i);
        if (item && item->GetItemID() == itemId) {
            actualCount += item->GetNumber();
        }
    }
    
    return actualCount == expectedCount;
}

// 验证金钱数量
void BagSystemTestBase::VerifyMoneyAmount(NFPlayer* player, int moneyType, int64_t expectedAmount) {
    ASSERT_NE(player, nullptr) << "玩家对象不能为空";
    
    int64_t actualAmount = NFServicePackage::GetMoneyNumber(player, moneyType);
    ASSERT_EQ(actualAmount, expectedAmount) << "金钱数量不符合预期";
}

// 填充背包到指定容量
void BagSystemTestBase::FillBagToCapacity(NFBagPage* bagPage, int itemId, int count) {
    if (!bagPage) {
        return;
    }
    
    for (int i = 0; i < count && i < bagPage->GetMaxGrid(); ++i) {
        NFGridItem item = CreateTestItem(itemId, 1);
        // bagPage->SetItem(i, item);
    }
}

// 清空背包
void BagSystemTestBase::ClearBag(NFBagPage* bagPage) {
    if (!bagPage) {
        return;
    }
    
    for (int i = 0; i < bagPage->GetMaxGrid(); ++i) {
        // bagPage->ClearItem(i);
    }
}

// 获取随机物品ID
int BagSystemTestBase::GetRandomItemId() {
    std::vector<int> itemIds = {
        TEST_ITEM_NORMAL,
        TEST_ITEM_EQUIP,
        TEST_ITEM_CONSUMABLE,
        TEST_ITEM_MATERIAL,
        TEST_ITEM_STACKABLE,
        TEST_ITEM_UNIQUE
    };
    
    std::uniform_int_distribution<int> dist(0, itemIds.size() - 1);
    return itemIds[dist(m_randomGen)];
}

// 获取随机数量
int BagSystemTestBase::GetRandomCount(int min, int max) {
    std::uniform_int_distribution<int> dist(min, max);
    return dist(m_randomGen);
}

// 生成测试用的物品ID列表
std::vector<int> BagSystemTestBase::GenerateTestItemIds(int count) {
    std::vector<int> itemIds;
    
    for (int i = 0; i < count; ++i) {
        itemIds.push_back(10000 + i);
    }
    
    return itemIds;
} 